﻿using System;
using System.Collections.Generic;
using System.Web;
using Drill.Core;
using Drill.LocatorPattern;

namespace Drill.Integration.Web
{
	/// <summary>
	/// <see cref="IRootPathProvider"/> implementation that provides 
	/// absolute path resolution support for ASP.NET web application paths within Drill.
	/// </summary>
	public class AspNetRootPathProvider : IRootPathProvider
	{
		private readonly ILocator<HttpContextBase> _httpContextLocator;

		/// <summary>
		/// Initializes a new instance of the <see cref="AspNetRootPathProvider" /> class.
		/// </summary>
		public AspNetRootPathProvider()
			: this(new HttpContextLocator())
		{
		}

		/// <summary>
		/// Initializes a new instance of the <see cref="AspNetRootPathProvider" /> class.
		/// </summary>
		/// <param name="httpContextLocator">An <see cref="HttpContextLocator"/> instance.</param>
		/// <exception cref="System.ArgumentNullException">httpContextLocator</exception>
		public AspNetRootPathProvider(ILocator<HttpContextBase> httpContextLocator)
		{
			if (null == httpContextLocator)
			{
				throw new ArgumentNullException("httpContextLocator");
			}
			_httpContextLocator = httpContextLocator;
		}

		/// <summary>
		/// Gets a list of valid root paths.
		/// </summary>
		/// <returns>A list of valid root paths.</returns>
		public virtual IList<string> GetRootPaths()
		{
			// For ASP.NET, we return the mapped "~/" and "~/bin" directories 
			// which requires HttpContext, otherwise return an empty list.
			List<string> list = new List<string>();
			HttpContextBase httpContext = _httpContextLocator.Locate();
			if (null == httpContext || null == httpContext.Server)
			{
				return list;
			}

			HttpServerUtilityBase serverUtility = httpContext.Server;

			List<string> pathsToMap = new List<string> { "~/", "~/bin" };

			pathsToMap.ForEach(path => {
					string mappedPath = serverUtility.MapPath(path);
					if (false == string.IsNullOrWhiteSpace(mappedPath))
					{
						list.Add(mappedPath);
					}
				});

			return list;
		}
	}
}
